<?php defined('SYSPATH') or die('No direct access allowed.');

class Model_Api_V2_Food
{
    /**
     * 类型ID
     */
    const TYPE_ID = 121;

    /**
     * 搜索
     * @param $params
     * @return array
     */
    public static function search($params)
    {
        /**
         * @var $id
         * @var $dest_id
         * @var $sort_type
         * @var $attr_id
         * @var $category_id
         * @var $keyword
         * @var $lng
         * @var $lat
         * @var $offset
         * @var $pagesize
         */
        extract($params);

        $builder = DB::select(DB::expr('`sline_a`.*,(IFNULL(`sline_a`.bookcount,0)+IFNULL(`sline_b`.sell_num,0)) AS sell_num'))
            ->from(array('food', 'a'));

        if (!empty($dest_id)) {
            $builder->join('kindorderlist', 'left')
                ->on('a.id', '=', DB::expr('`sline_kindorderlist`.aid'))
                ->on('a.webid', '=', DB::expr('`sline_kindorderlist`.webid'))
                ->on('kindorderlist.typeid', '=', self::TYPE_ID)
                ->on('kindorderlist.classid', '=', DB::expr("{$dest_id}"));
            $order_by = "IFNULL(`sline_kindorderlist`.displayorder,9999) ASC";
        } else {
            $builder->join('allorderlist', 'left')
                ->on('a.id', '=', DB::expr('`sline_allorderlist`.aid'))
                ->on('a.webid', '=', DB::expr('`sline_allorderlist`.webid'))
                ->on('allorderlist.typeid', '=', self::TYPE_ID);
            $order_by = "IFNULL(`sline_allorderlist`.displayorder,9999) ASC";
        }

        // 需要提前处理真实购买量
        $builder->join(array('member_order_statistic', 'b'), 'left')
            ->on('b.product_id', '=', DB::expr('`sline_a`.id'))
            ->on('b.type_id', '=', self::TYPE_ID);

        $builder->where('a.ishidden', '=', 0)
            ->and_where('a.status', '=', 3);

        if (!empty($keyword)) {
            $builder->and_where('a.title', 'like', '%' . $keyword . '%');
        }


        if (!empty($id)) {
            $builder->and_where('a.id', '=', $id);
        }

        //按属性
        if (!empty($attr_id)) {
            $attr_where = self::get_attr_where($attr_id);
            if ($attr_where) {
                $builder->and_where(DB::expr($attr_where));
            }
        }

        //按类目
        if (!empty($category_id)) {
            $category_where = self::get_category_where($category_id);
            if ($category_where) {
                $builder->and_where(DB::expr($category_where));
            }
        }

        if (!empty($dest_id)) {
            $builder->and_where(DB::expr(" AND FIND_IN_SET({$dest_id},sline_a.kindlist)"));
        }

        if (!empty($lng) && !empty($lat)) {
            $lat = round($lat, 3);
            $lng = round($lng, 3);
            $builder->and_where(DB::expr(" AND sline_a.lat > ({$lat}-500) AND sline_a.lat < ({$lat}+500) AND sline_a.lng > ({$lng}-500) AND sline_a.lng < ({$lng}+500)"));
            $coordinate_order_by = " ACOS(SIN(({$lat} * 3.1415) / 180 ) * SIN((sline_a.lat * 3.1415) / 180 )  ";
            $coordinate_order_by .= " + COS(({$lat} * 3.1415) / 180 ) * COS((sline_a.lat * 3.1415) / 180 ) ";
            $coordinate_order_by .= " *COS(({$lng} * 3.1415) / 180 - (sline_a.lng * 3.1415) / 180 ) ) * 6380 ASC ";
        }

        if (!empty($sort_type)) {
            switch ($sort_type) {
                case 1:
                    $order_by = " sline_a.price ASC";
                    break;
                case 2:
                    $order_by = " sline_a.price DESC";
                    break;
                case 3:
                    $order_by = " sell_num DESC";
                    break;
                case 4:
                    $order_by = " sline_a.satisfyscore DESC";
                    break;
                case 0:
                    if ($coordinate_order_by) {
                        $order_by = $coordinate_order_by.','.$order_by;
                    }
                    break;
                default:
                    break;
            }
        }

        $total = $builder->execute()->count();
        $list  = $builder->offset($offset)->limit($pagesize)->order_by(DB::expr($order_by))->execute()->as_array();
        return array('total' => $total, 'list' => $list);
    }

    /**
     * 属性生成where条件,用于多条件属性搜索.
     * @param $attr_id
     * @return string
     */
    public static function get_attr_where($attr_id)
    {
        $data = Common::remove_arr_empty(explode('_', $attr_id));
        $str  = '';
        foreach ($data as $value) {
            $value = intval($value);
            if ($value != 0) {
                $str .= " and FIND_IN_SET($value,sline_a.attrid) ";
            }
        }
        return $str;
    }

    public static function get_category_where($category_id)
    {
        $data = Common::remove_arr_empty(explode('_', $category_id));
        $str  = '';
        foreach ($data as $value) {
            $value = intval($value);
            if ($value != 0) {
                $str .= " and FIND_IN_SET($value,sline_a.category_id) ";
            }
        }
        return $str;
    }


    /**
     * 获取距离
     * @param $latitude_a
     * @param $longitude_a
     * @param $latitude_b
     * @param $longitude_b
     * @return false|string
     */
    public static function get_distance_by_geo($latitude_a, $longitude_a, $latitude_b, $longitude_b)
    {
        $geo_conf = array(
            'pi' => pi(),
            'EARTH_RADIUS' => 6378.137,
        );
        if (!$longitude_a || !$latitude_a || !$longitude_a || !$longitude_b) {
            return false;
        }
        $latitude_a_radian     = self::angle_to_radian($latitude_a);
        $latitude_b_radian     = self::angle_to_radian($latitude_b);
        $longitude_a_radian    = self::angle_to_radian($longitude_a);
        $longitude_b_radian    = self::angle_to_radian($longitude_b);
        $latitude_radian_diff  = $latitude_a_radian - $latitude_b_radian;
        $longitude_radian_diff = $longitude_a_radian - $longitude_b_radian;
        $S                     = 2 * asin(sqrt(pow(sin($latitude_radian_diff / 2), 2) + cos($latitude_a_radian) * cos($latitude_b_radian) * pow(sin($longitude_radian_diff / 2), 2))) * $geo_conf['EARTH_RADIUS'];
        if ($S < 1) {
            $S = sprintf("%.2f", $S * 1000) . 'm';
        } else {
            $S = sprintf("%.2f", $S) . 'km';
        }
        return $S;
    }

    public static function angle_to_radian($angle)
    {
        $geo_conf = array(
            'pi' => pi(),
            'EARTH_RADIUS' => 6378.137,
        );
        return $angle * $geo_conf['pi'] / 180.0;
    }

    //获取营业时间
    public static function get_biz_time($productid)
    {
        $wek_map    = [
            '1' => "周一",
            '2' => "周二",
            '3' => "周三",
            '4' => "周四",
            '5' => "周五",
            '6' => "周六",
            '7' => "周日",
        ];
        $sql        = "select * from sline_food_time where productid={$productid}";
        $arr        = DB::query(1, $sql)->execute()->as_array();
        $biz_time   = [];
        $biz_status = 0;//1当前营业中
        $w          = date('w');
        if (!$w) {
            $w = 7;
        }
        $w    = intval($w);
        $day  = date('Y-m-d');
        $time = time();
        foreach ($arr as $k => $v) {
            $start_week   = $wek_map[$v['start_week']];
            $end_week     = $wek_map[$v['end_week']];
            $start_hour   = $v['start_hour'];
            $end_hour     = $v['end_hour'];
            $biz_time_str = $start_week . "至" . $end_week . " " . "{$start_hour}-{$end_hour}";
            $biz_time[]   = $biz_time_str;
            //计算当前是否是营业中
            if (!$biz_status && $v['start_week'] <= $w && $w <= $v['end_week']) {
                $day_start = $day . ' ' . $start_hour;
                $day_end   = $day . ' ' . $end_hour;
                $day_start = strtotime($day_start);
                $day_end   = strtotime($day_end);
                if ($day_start <= $time && $day_end >= $time) {
                    $biz_status = 1;
                }
            }
        }
        $data['biz_time']   = $biz_time;
        $data['biz_status'] = $biz_status;
        return $data;
    }


    /**
     * 获取套餐
     * @param $product_id
     * @param $params
     * @return array
     * @throws Kohana_Exception
     */

    public static function suit($product_id, $params = array())
    {
        $query = ORM::factory('food_suit')
            ->where("productid=:productid");
        if ($params['card_suit_id']) {
            $query->and_where('id', 'in', explode(',', $params['card_suit_id']));
        }
        $suit = $query->order_by('displayorder', 'ASC')
            ->param(':productid', $product_id)
            ->get_all();
        foreach ($suit as &$r) {
            $r['dishes_list'] = [];
            if ($r['dishes']) {
                $r['dishes_list'] = json_decode($r['dishes'], true);
            }
            $r['litpic']       = Model_Api_V2_System::uniapp_img($r['litpic']);
            $r['description']  = Model_Api_V2_Xcx::filter_content($r['description']);
            $r['sales_volume'] = DB::select()
                ->from('member_order')
                ->where("productautoid={$product_id} and suitid={$r['id']}")
                ->execute()
                ->count();
        }
        return $suit;
    }

    /**
     * 通过id获取套餐
     * @param $id
     * @return array|mixed
     */
    public static function suit_by_id($id)
    {
        $suit = DB::select('id', 'productid', 'suitname', 'sellpoint', 'description', 'number', 'sellprice', 'price'
            , 'auto_close_time', 'is_confirm_pay', 'is_confirm_refund', 'refund_restriction', 'max_number'
            , 'litpic', 'pay_way', 'dishes','at_least'
        )
            ->from('food_suit')
            ->where('id', '=', $id)
            ->execute()
            ->current();
        if ($suit) {
            $suit['dishes_list'] = [];
            if ($suit['dishes']) {
                $suit['dishes_list'] = json_decode($suit['dishes'], true);
            }
            $suit['litpic']      = Model_Api_V2_System::uniapp_img($suit['litpic']);
            $suit['description'] = Model_Api_V2_Xcx::filter_content($suit['description']);
        }
        return $suit;
    }

    /**
     * 获取指定指定字段的的线路信息
     * @param $id
     * @param $field
     * @return mixed|null
     */
    public static function get_detail($id, $field = '')
    {
        $field = $field ? DB::expr($field) : '*';
        return DB::select($field)
            ->from('food')
            ->where('id', '=', $id)
            ->execute()
            ->current();
    }

    /**
     * 获取套餐信息
     * @param $suit_id
     * @param $product_id
     * @return mixed|null
     */
    public static function suit_info($suit_id, $product_id = null)
    {
        $model = DB::select()
            ->from('food_suit')
            ->where('id', '=', $suit_id);
        if ($product_id) {
            $model->and_where('productid', '=', $product_id);
        }
        return $model->execute()->current();
    }

    /**
     * 检查预定参数
     * @param $request_params
     * @param $member_id
     * @return array
     * @throws Exception
     */
    public static function check_order_params($request_params, $member_id)
    {
        $product_id = $request_params['product_id'];
        $suit_id    = $request_params['suit_id'];

        // 产品信息
        $info = self::get_detail($product_id);
        if (!$info) {
            throw new Exception('产品不存在');
        }

        if ($info['status'] != 3) {
            throw new Exception('产品已下架，不可预订');
        }

        // 套餐信息
        $suit_info = self::suit_info($suit_id, $product_id);
        if (!$suit_info) {
            throw new Exception('套餐不存在');
        }

        if ($suit_info['price'] <= 0) {
            throw new Exception('套餐价格异常，不可预订');
        }

        // 验证联系人
        $cfg_plugin_food_booking_need = Model_Sysconfig::get_configs(0, 'cfg_plugin_food_booking_need',true);
        $cfg_plugin_food_booking_need = json_decode($cfg_plugin_food_booking_need,true);
        if(isset($cfg_plugin_food_booking_need['name']) && $cfg_plugin_food_booking_need['name'] ){
            $linkman = trim($request_params['linkman']);
            if (!$linkman) {
                throw new Exception('联系人不能为空');
            }
        }

        if(isset($cfg_plugin_food_booking_need['phone']) && $cfg_plugin_food_booking_need['phone'] ){
            $linkman = trim($request_params['linktel']);
            if (!$linkman) {
                throw new Exception('电话不能为空');
            }
        }

        if(isset($cfg_plugin_food_booking_need['email']) && $cfg_plugin_food_booking_need['email'] ){
            $linkman = trim($request_params['linkemail']);
            if (!$linkman) {
                throw new Exception('邮件不能为空');
            }
        }

        if(isset($cfg_plugin_food_booking_need['remark']) && $cfg_plugin_food_booking_need['remark'] ){
            $linkman = trim($request_params['remark']);
            if (!$linkman) {
                throw new Exception('备注不能为空');
            }
        }


        //成人数量
        $ding_num = $request_params['dingnum'];
        //判断最大购买数量
        if ($suit_info['max_number'] != -1 && $ding_num > $suit_info['max_number']) {
            throw new Exception('超出最大购买数量:'.$suit_info['max_number'] );
        }

        //判断最大购买数量
        if ($suit_info['at_least']>0 && $ding_num < $suit_info['at_least']) {
            throw new Exception('小于起购数：'.$suit_info['at_least']);
        }

        // 检查拼团或凑团限制
        $together_id = Arr::get($request_params, 'together_id', 0);
        $join_id = Arr::get($request_params, 'join_id', 0);
        if ($together_id > 0 || $join_id > 0) {
            $together_params      = array('join_id' => $join_id, 'ding_num' => $ding_num);
            $check_order_together = Model_Api_V2_Together::check_order_together($together_id, $member_id, $together_params);
            if (!$check_order_together['status']) {
                throw new Exception($check_order_together['msg']);
            }
            $together_info  = $check_order_together['data'];
            $together_price = $together_info['price'];
            // 更新套餐价格
            $suit_info['price'] = $together_price['adult_price'];
        }

        $suit_info['price'] = Currency_Tool::price($suit_info['price']);

        $extend_data = array();
        if (isset($together_info)) {
            $extend_data['together_info'] = $together_info;
        }

        return array($info, $suit_info, $extend_data);
    }

    /**
     * 生成订单信息
     * @param $request_params
     * @param $info
     * @param $suit
     * @param $extend_data
     * @param $user_info
     * @return array
     * @throws Exception
     */
    public static function make_order($request_params, $info, $suit, $extend_data, $user_info)
    {
        // 订单编号
        $ordersn = Product::get_ordersn(self::TYPE_ID);

        // 联系人信息
        $linkman   = trim($request_params['linkman']);
        $linktel   = $request_params['linktel'];
        $linkemail = Arr::get($request_params, 'linkemail', '');

        // 备注信息
        $remark =  Arr::get($request_params, 'remark', '');
        // 订单来源 1PC,2WAP,3小程序,4平台添加
        $source = Arr::get($request_params, 'source', '');
        $source = $source ?: 3;
        // 成人数量
        $dingnum = $request_params['dingnum'];
        // 使用时间
        $use_date = Arr::get($request_params, 'usedate', '');
        $use_date = $use_date ?: '';

        // 判断是否需要管理员手动确认
        $need_confirm = $suit['is_confirm_pay'];

        // 退款限制
        $refund_restriction = $suit['is_confirm_refund'] ? 2 : $suit['refund_restriction'];

        //积分抵现.
        $jifen_info = self::make_jifen_data($request_params, $info, $user_info);
        $order = array(
            'ordersn' => $ordersn,
            'litpic' => $info['litpic'],
            'typeid' => self::TYPE_ID,
            'productautoid' => $info['id'],
            'productaid' => $info['aid'],
            'productname' => $info['title'],
            'departdate' => '',
            'memberid' => $user_info['mid'],
            'suitid' => $suit['id'],
            'suit_name' => $suit['suitname'],
            'dingnum' => $dingnum,
            'childnum' => 0,
            'oldnum' => 0,
            'people4_num' => 0,
            'people5_num' => 0,
            'people6_num' => 0,
            'webid' => 0,
            'addtime' => time(),
            'linkman' => $linkman,
            'linktel' => $linktel,
            'linkemail' => $linkemail,
            'remark' => $remark,
            'source' => $source,
            'usedate' => $use_date,
            'need_confirm' => $need_confirm,
            'refund_restriction' => $refund_restriction,
            'auto_close_time' => $refund_restriction,
            'paytype' => 1,
            'pay_way' => 1,
            'dingjin' => 0,
            'childprice' => 0,
            'oldprice' => 0,
            'people4_price' => 0,
            'people5_price' => 0,
            'people6_price' => 0,
            'roombalance' => 0,

            'needjifen' => $jifen_info['need_jifen'],
            'usejifen' => $jifen_info['use_jifen'],
            'jifentprice' => $jifen_info['jifen_price'],
            'jifencomment' => $jifen_info['jifen_comment'],
        );
        // 价格处理
        $order['price'] = doubleval($suit['price']);

        // 自动关闭订单时间
        $auto_close_time = $suit['auto_close_time'] ?: 0;
        if ($auto_close_time) {
            $order['auto_close_time'] = $auto_close_time + time();
        }

        // 待确认时限
        $auto_confirm_time = $suit['auto_confirm_time'] ?: 0;
        if ($auto_confirm_time) {
            $order['auto_confirm_time'] = $auto_confirm_time + time();
        }

        //自动退款时限
        $use_date=trim($request_params['use_date']);
        $no_confirm_refund = $suit['no_confirm_refund'] ?: 0;
        if ($no_confirm_refund) {
            $order['no_confirm_refund'] = strtotime($use_date . ' +1 day') -  $no_confirm_refund ;
        }


        return $order;
    }


    public static function make_jifen_data($params, $info, $member_info)
    {
        $need_jifen  = Arr::get($params, 'need_jifen', 0);
        $jifen_price = 0;
        $use_jifen   = 0;
        if ($need_jifen) {
            $jifen_price = Model_Jifen_Price::calculate_jifentprice($info['jifentprice_id'], self::TYPE_ID, $need_jifen, $member_info);
            $use_jifen   = empty($jifen_price) ? 0 : 1;
            $need_jifen  = empty($jifen_price) ? 0 : $need_jifen;
        }

        //积分评论
        $jifen_comment_info = Model_Jifen::get_used_jifencomment(self::TYPE_ID);
        $jifen_comment      = empty($jifen_comment_info) ? 0 : $jifen_comment_info['value'];

        return compact('need_jifen', 'use_jifen', 'jifen_comment', 'jifen_price');
    }

    /**
     * 添加发票
     * @param $order_id
     * @param $request_data
     * @return void
     */
    public static function add_bill_info($order_id, $request_params)
    {
        // 订单发票信息
        $receipt = $request_params['receiptInfo'];
        if ($receipt) {
            $receiptInfo = json_decode($receipt, true);
            if ($receiptInfo) {
                //发票
                $invoice_type = $receiptInfo['type'];
                $bill_info    = array(
                    'title' => $receiptInfo['title'],
                    'content' => $receiptInfo['content'],
                    'type' => $invoice_type,
                    'taxpayer_number' => $invoice_type != 0 ? $receiptInfo['taxpayer_number'] : '',
                    'taxpayer_address' => $invoice_type == 2 ? $receiptInfo['taxpayer_address'] : '',
                    'taxpayer_phone' => $invoice_type == 2 ? $receiptInfo['taxpayer_phone'] : '',
                    'bank_branch' => $invoice_type == 2 ? $receiptInfo['bank_branch'] : '',
                    'bank_account' => $invoice_type == 2 ? $receiptInfo['bank_account'] : ''
                );

                // 发票地址
                if (isset($receiptInfo['address']) && !empty($receiptInfo['address'])) {
                    $receiptAddress        = $receiptInfo['address'];
                    $bill_info['mobile']   = $receiptAddress['phone'];
                    $bill_info['receiver'] = $receiptAddress['receiver'];
                    $bill_info['postcode'] = $receiptAddress['postcode'];
                    $bill_info['province'] = $receiptAddress['province'];
                    $bill_info['city']     = $receiptAddress['city'];
                    $bill_info['address']  = $receiptAddress['address'];
                }

                Model_Member_Order_Bill::add_bill_info($order_id, $bill_info);
            }
        }
    }

    /**
     * 保存菜品信息
     * @param $order_id
     * @param $suit
     * @return void
     */
    public static function add_order_dishes($order_id, $suit)
    {
        $order_suit_model          = ORM::factory('food_order_suit');
        $order_suit_model->orderid = $order_id;
        $order_suit_model->dishes  = $suit['dishes'];
        $order_suit_model->save();
    }
}